package fm.admin.controller;

import com.alibaba.fastjson.JSON;
import com.mongodb.DBObject;
import com.mongodb.gridfs.CLI;
import fm.cache.ConfigCache;
import fm.controller.BaseController;
import fm.dto.NeiyiUser;
import fm.dto.SystemUser;
import fm.entity.ArticleComment;
import fm.entity.OrderArticleAd;
import fm.entity.Section;
import fm.entity.SectionPayResolve;
import fm.entityEnum.ArticleAdEnum;
import fm.entityEnum.ClientTypeEnum;
import fm.entityEnum.ProductTypeEnum;
import fm.exception.BizException;
import fm.exception.TokenInvalidException;
import fm.mongo.MCondition;
import fm.mongo.MRel;
import fm.util.CommonUtils;
import fm.web.CurrentRequest;
import fm.web.MediaTypes;
import fm.yichenet.dto.ArticleDto;
import fm.yichenet.mongo.service.ArticleService;
import fm.yichenet.service.OrderService;
import fm.yichenet.service.SectionService;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * Created by 宏炜 on 2017-05-26.
 */
@Controller
@RequestMapping("article")
public class ArticleController extends BaseController {

    @Autowired
    ArticleService articleService;
    @Autowired
    OrderService orderService;
    @Autowired
    SectionService sectionService;

    @ResponseBody
    @RequestMapping(value = "mergeArticle", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public String mergeArticle(@RequestBody ArticleDto articleDto, ModelMap modelMap) throws Exception {
        modelMap.clear();
        try {
            articleService.mergeArticle(articleDto);
            this.success(modelMap);
        } catch (BizException ex) {
            this.failed(modelMap, ex);
        }
        return JSON.toJSONString(modelMap);
    }

    @ResponseBody
    @RequestMapping(value = "/ad/{clientType}/{flag}", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public String topArticle(@RequestParam(value = "id", required = true) String id,
                             HttpServletRequest request, @PathVariable ClientTypeEnum clientType,
                             @PathVariable ArticleAdEnum flag, String resolveKey) throws Exception {
        Map data = new HashMap();
        try {
            DBObject article = articleService.getArticleInfo(id);
            if (CommonUtils.isEmpty(article)) {
                throw new BizException("未找到对应的文章，请刷新后重试！");
            }

            Section section = sectionService.getById((Long) article.get("section_id"));
            SectionPayResolve resolve = null;
            switch (flag) {
                case BANNER:
                    if (section.getPayForBanner() == 1) {
                        resolve = section.getPayForBannerResolve();
                        OrderArticleAd order = orderService.addArticleAdOrder(id, resolve.getPrice(resolveKey), flag, SectionPayResolve.getStartTime(resolveKey), SectionPayResolve.getEndTime(resolveKey));
                        Object prepayResult = orderService.prePayOrder(order.getId() + "", clientType, ProductTypeEnum.FORUM_AD, request);
                        data.put("data", prepayResult);
                        data.put("total", order.getTotal());
                    } else {
                        //不需要支付，直接增加标记
                        articleService.addFlag(id, flag, resolve.getStartTime(resolveKey), resolve.getEndTime(resolveKey));
                    }
                    break;
                case LIST_TOP:
                    if (section.getPayForTop() == 1) {
                        resolve = section.getPayForTopResolve();
                        OrderArticleAd order = orderService.addArticleAdOrder(id, resolve.getPrice(resolveKey), flag, SectionPayResolve.getStartTime(resolveKey), SectionPayResolve.getEndTime(resolveKey));
                        Object prepayResult = orderService.prePayOrder(order.getId() + "", clientType, ProductTypeEnum.FORUM_AD, request);
                        data.put("total", order.getTotal());
                        data.put("data", prepayResult);
                    } else {
                        //不需要支付，直接增加标记
                        articleService.addFlag(id, flag, resolve.getStartTime(resolveKey), resolve.getEndTime(resolveKey));
                    }
                    break;
                default:
                    throw new BizException("参数错误!");
            }
            this.success(data);
        } catch (BizException ex) {
            this.failed(data, ex);
            LOGGER.error("occur biz error:", ex);
        } catch (Exception ex) {
            this.failed(data, "服务器发生未知错误，请联系管理员解决！");
            LOGGER.error("occur error", ex);
        }
        return JSON.toJSONString(data);
    }


    @ResponseBody
    @RequestMapping(value = "/ad/remove/{type}", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public String unTopArticle(@RequestParam(value = "id", required = true) String id, @PathVariable ArticleAdEnum type) throws Exception {
        Map data = new HashMap();
        try {
            articleService.removeFlag(id, type);
            this.success(data);
        } catch (BizException ex) {
            this.failed(data, ex);
        }
        return JSON.toJSONString(data);
    }

    @ResponseBody
    @RequestMapping(value = "getArticleList", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public String getArticleList(@RequestParam(value = "pageNum", required = false) Integer pageNum,
                                 @RequestParam(value = "pageSize", required = false) Integer pageSize,
                                 @RequestParam(value = "type", required = true) Integer type,
                                 @RequestParam(value = "keyword", required = false, defaultValue = "") String keyword,
                                 Long sectionId,
                                 ModelMap modelMap) throws Exception {
        try {
            keyword = URLDecoder.decode(keyword, "utf-8");
            Map<String, Object> params = new HashedMap();

            if (!"".equals(keyword) && !CommonUtils.isEmpty(keyword)) {
                if (type.equals(1)) {
                    MCondition mc = MCondition.create(MRel.regex).append("main_title", Pattern.compile(keyword));
                    params.putAll(mc.toDBObject().toMap());
                    MCondition mcSub = MCondition.create(MRel.regex).append("sub_title", Pattern.compile(keyword));
                    params.putAll(mcSub.toDBObject().toMap());
                } else {
                    MCondition mcCon = MCondition.create(MRel.regex).append("content", Pattern.compile(keyword));
                    params.putAll(mcCon.toDBObject().toMap());
                }
            }
            SystemUser user = (SystemUser) CurrentRequest.getCurrentLoginUser();

            if (!isAdmin()) {
                params.put("user_id", user.getId());
            }
            if (sectionId != null) {
                params.put("section_id", sectionId);
            }
            params.put("type", type);
            List<DBObject> articles = articleService.getArticleForPage(params, pageSize, pageNum);
            Long total = articleService.countArticles(params);
            modelMap.put("data", articles);
            modelMap.put("total", total);
            this.success(modelMap);
        } catch (BizException ex) {
            this.failed(modelMap, ex);
        }
        return JSON.toJSONString(modelMap);
    }

    /**
     * 获取图文文章详情
     *
     * @param article_id
     * @param modelMap
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "getArticleInfo", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public String getArticleInfo(@RequestParam(value = "article_id", required = true) String article_id, ModelMap modelMap) throws Exception {
        modelMap.clear();
        try {
            DBObject articleInfo = articleService.getArticleInfo(article_id);
            articleInfo.removeField("likes");
            articleInfo.removeField("comments");
            modelMap.put("data", articleInfo);
            this.success(modelMap);
        } catch (BizException ex) {
            this.failed(modelMap, ex);
        }
        return JSON.toJSONString(modelMap);
    }

    @ResponseBody
    @RequestMapping(value = "delArticle", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public String delArticle(@RequestParam(value = "id", required = true) String id, ModelMap modelMap) throws Exception {
        modelMap.clear();
        try {
            articleService.deleteArticle(id);
            this.success(modelMap);
        } catch (BizException ex) {
            this.failed(modelMap, ex);
        }
        return JSON.toJSONString(modelMap);
    }

    @ResponseBody
    @RequestMapping(value = "getUserInfoList", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public Map getUserArticleList(String user_id) {
        Map res = new HashMap();
        try {
            Map param = new HashMap();
            param.put("user_id", user_id);
            List<DBObject> articleList = articleService.getInfoArticleListByparam(param);
            res.put("data", articleList);
            this.success(res);
        } catch (BizException ex) {
            LOGGER.error("发生错误:", ex);
            this.failed(res, ex.getMessage());
        } catch (Exception ex) {
            LOGGER.error("发生异常", ex);
            this.failed(res, "服务器发生了未知的错误，请联系管理员或者开发者解决!");
        }
        return res;
    }

    /**
     * 多条件搜索资讯
     *
     * @param pageNum
     * @param pageSize
     * @param type
     * @param keyword
     * @param section_id
     * @param sort
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "getSearchList", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public Map getSearchList(@RequestParam(value = "pageNum", required = false) Integer pageNum,
                             @RequestParam(value = "pageSize", required = false) Integer pageSize,
                             @RequestParam(value = "type", required = false) Integer type,
                             @RequestParam(value = "keyword", required = false, defaultValue = "") String keyword, Long section_id,String user_id,
                             String sort, ArticleAdEnum ad_option) throws Exception {
        Map res = new HashMap();
        try {
            keyword = URLDecoder.decode(keyword, "utf-8");
            Map<String, Object> params = new HashedMap();
            MCondition allMc = MCondition.create(MRel.and);

            if (!"".equals(keyword) && !CommonUtils.isEmpty(keyword)) {
                MCondition keywordMatchCondition = MCondition.create(MRel.or);
                keywordMatchCondition.append(MCondition.create(MRel.regex).append("main_title", Pattern.compile(keyword)));
                keywordMatchCondition.append(MCondition.create(MRel.regex).append("sub_title", Pattern.compile(keyword)));
                allMc.append(keywordMatchCondition);
            }


            if (!CommonUtils.isEmpty(type)) {
                allMc.append("type", type);
            }
            if(!CommonUtils.isEmpty(section_id)){
                allMc.append("section_id",section_id);

            }
            if(!CommonUtils.isEmpty(user_id)){
                allMc.append("user_id",user_id);
            }
            if(ad_option!=null){
                allMc.append(MCondition.create(MRel.exists).append("ad_option." + ad_option.toString(), true));
            }
            params = allMc.toDBObject().toMap();
            if (StringUtils.isEmpty(keyword) && section_id == null && type == null &&
                    StringUtils.isEmpty(user_id) && ad_option==null) {
                params = new HashMap();
            }
            List<DBObject> articles = articleService.getArticleForPage(params, pageSize, pageNum);
            Long total = articleService.countArticles(params);
            res.put("data", articles);
            res.put("total", total);
            this.success(res);
        } catch (BizException ex) {
            this.failed(res, ex);
        }
        return res;
    }
    /***
     * 评论图文文章
     * @param articleComment
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "/commentArticle")
    public Map commentArticle(@RequestBody ArticleComment articleComment) throws Exception {
        HashMap res = new HashMap();
        articleComment.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        try {
            if(CurrentRequest.isAdmin()){
                SystemUser user = (SystemUser) getCurrentUser();
                articleComment.setUser_id(user.getId());
                articleComment.setUser_nickname(CommonUtils.isEmpty(user.getName()) ? "" : user.getName());
                articleComment.setUser_head_img_url(CommonUtils.isEmpty(ConfigCache.getConfig("DEFAULT_LOGO")) ? "" : ConfigCache.getConfig("DEFAULT_LOGO"));
            }
            else {
                NeiyiUser user = (NeiyiUser) getCurrentUser();
            articleComment.setUser_id(user.getId());
            articleComment.setUser_nickname(CommonUtils.isEmpty(user.getCompanyName()) ? "" : user.getCompanyName());
            articleComment.setUser_head_img_url(CommonUtils.isEmpty(user.getUserLogo()) ? "" : user.getUserLogo());
        }
        DBObject dbObject = articleService.commentArticle(articleComment);

            res.put("data", dbObject);
            this.success(res);
        }
        catch (TokenInvalidException ex){
            LOGGER.error("发生错误:",ex);
            this.failed(res,"请先登录!");
        }catch (BizException ex) {
            this.failed(res, ex.getMessage());
        }
        return res;
    }

    /**
     *
     * @param article_id
     * @param content
     * @param to_user_id
     * @param modelMap
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "addComment", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public String addComment(String article_id,String content,String to_user_id, ModelMap modelMap) throws Exception {
        modelMap.clear();
        try {
            ArticleComment articleComment = new ArticleComment();
            NeiyiUser user = (NeiyiUser) getCurrentUser();
            articleComment.setUser_id(user.getId());
            articleComment.setUser_nickname(CommonUtils.isEmpty(user.getCompanyName()) ? "" : user.getCompanyName());
            articleComment.setUser_head_img_url(CommonUtils.isEmpty(user.getUserLogo()) ? "" : user.getUserLogo());
            articleComment.setContent(content);
            articleComment.setArticle_id(article_id);
            articleComment.setTo_user_id(to_user_id);
            DBObject dbObject = articleService.commentArticle(articleComment);
            modelMap.put("data", dbObject);
            this.success(modelMap);
        } catch (BizException ex) {
            this.failed(modelMap, ex);
        }
        return JSON.toJSONString(modelMap);
    }

    /**
     *
     * @param article_id
     * @param flag
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "articleCollect",method = RequestMethod.POST,produces = MediaTypes.JSON_UTF_8)
    public Map articleCollect(String article_id,boolean flag){
        Map res = new HashMap();
        try{
            articleService.articleCollect(article_id,flag);
            res.put("flag",true);
            this.success(res);
        }
        catch (TokenInvalidException ex){
            LOGGER.error("发生错误:",ex);
            this.failed(res,"请先登录!");
        }
        catch (BizException ex){
            LOGGER.error("发生错误:",ex);
            this.failed(res,ex.getMessage());
        }catch (Exception ex){
            LOGGER.error("发生异常",ex);
            this.failed(res,"服务器发生了未知的错误，请联系管理员或者开发者解决!");
        }
        return res;
    }
    /**
     * 获取评论列表
     *
     * @param pageNum
     * @param pageSize
     * @param article_id
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "/getCommentsList", method = RequestMethod.POST, produces = MediaTypes.JSON_UTF_8)
    public Map getCommentsList(@RequestParam(value = "pageNum", required = true) Integer pageNum,
                                  @RequestParam(value = "pageSize", required = true) Integer pageSize,
                                  @RequestParam(value = "type", required = true) Integer type,
                                  @RequestParam(value = "article_id", required = true) String article_id) throws Exception {
        Map res = new HashMap();
        try {

            List<DBObject> comments = articleService.getCommentsList(pageSize, pageNum, article_id, type);
            Long total = articleService.countComments(article_id, type);
            res.put("data", comments);
            res.put("total", total);
            this.success(res);
        } catch (BizException ex) {
            this.failed(res, ex);
        }
        return res;
    }
        @ResponseBody
        @RequestMapping(value = "/commentlike",method = RequestMethod.POST,produces = MediaTypes.JSON_UTF_8)
        public Map commentLike(String id){
            Map res = new HashMap();
            try{
               articleService.commentLike(id);
                res.put("flag",true);
                this.success(res);
            }catch (BizException ex){
                LOGGER.error("发生错误:",ex);
                this.failed(res,ex.getMessage());
            }catch (Exception ex){
                LOGGER.error("发生异常",ex);
                this.failed(res,"服务器发生了未知的错误，请联系管理员或者开发者解决!");
            }
            return res;
        }
}
